
#include "stdafx.h"
#include "line.h"
#include "static_prog.h"


void load_static_program(char* file_name, SIZE_T file_len)
{
	FILE* file = fopen(file_name, "rb");
	if( !file ){
		printf("ERROR: can not open file\n");
		return ;
	}

	Elf32_Ehdr* elf_header = (Elf32_Ehdr*)malloc(sizeof(Elf32_Ehdr)); 
	fread(elf_header, sizeof(Elf32_Ehdr), 1, file);

	Elf32_Half ph_table_count = elf_header->e_phnum;
	Elf32_Half ph_entry_size = elf_header->e_phentsize;
	Elf32_Off ph_offset = elf_header->e_phoff;
	Elf32_Phdr* ph_table = (Elf32_Phdr*)malloc(ph_entry_size*ph_table_count);
	fseek(file, ph_offset, SEEK_SET);
	fread((void*)ph_table, ph_entry_size*ph_table_count, 1, file);
	SIZE_T ph_size = 0;
	for( int index = 0 ; index < ph_table_count; index++ ){
		Elf32_Phdr* ph_entry = &ph_table[index];
		if( ph_entry->p_type == PT_LOAD ){
			ph_size += ph_entry->p_memsz;
		}
	}

	ph_size += sizeof(Elf32_Ehdr);
	SIZE_T alloc_size = PAGE_SZIE*((ph_size % PAGE_SZIE) + ((ph_size / PAGE_SZIE == 0) ? 0 : 1));
	char* alloc_buf = (char*)VirtualAlloc((LPVOID)0x08048000, alloc_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if( !alloc_buf ){
		fclose(file);
		free(elf_header);
		free(ph_table);
		return;
	}

	for( int index = 0 ; index < ph_table_count; index++ ){
		Elf32_Phdr* ph_entry = &ph_table[index];
		if( ph_entry->p_type == PT_LOAD ){
			fseek(file, ph_entry->p_offset, SEEK_SET);
			fread((void*)ph_entry->p_vaddr, ph_entry->p_memsz, 1, file);
		}
	}
	fclose(file);
	free(elf_header);
	free(ph_table);

	elf_header = (Elf32_Ehdr*)0x08048000;
	Elf32_Addr entry = elf_header->e_entry;


	//now go into elf!
	__asm
	{
		push ARGV;
		push ARGC;
		jmp entry;
	}
}